package com.molichuxing.gateway.bff.financial.services.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.gateway.bff.dealer.services.impl.DealerBffServiceImpl;
import com.molichuxing.gateway.bff.financial.convertor.Convert;
import com.molichuxing.gateway.bff.financial.entity.request.create.EsignAccountCreateVo;
import com.molichuxing.gateway.bff.financial.entity.request.create.EsignCompanyCreateVo;
import com.molichuxing.gateway.bff.financial.entity.response.ContractLogVo;
import com.molichuxing.gateway.bff.financial.entity.response.ContractVo;
import com.molichuxing.gateway.bff.financial.entity.response.DeliveryVo;
import com.molichuxing.gateway.bff.financial.services.ContractBffService;
import com.molichuxing.services.business.dto.request.create.EsignAccountBizCreateDto;
import com.molichuxing.services.business.dto.request.create.EsignCompanyBizCreateDto;
import com.molichuxing.services.business.dto.response.OrderBizDto;
import com.molichuxing.services.business.service.EsignBizService;
import com.molichuxing.services.business.service.OrderBizService;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.ContractLogCreatedEnum;
import com.molichuxing.services.property.ContractLogGoodsTypeEnum;
import com.molichuxing.services.property.ContractStatusEnum;
import com.molichuxing.services.property.ContractTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 还款审核相关bff
 *
 * @author zhaopenghui
 * @date 2019年8月30日
 */
@Service("contractBffService")
public class ContractBffServiceImpl implements ContractBffService {
    private static final Logger logger = LoggerFactory.getLogger(DealerBffServiceImpl.class);

    @Resource
    private ContractService contractService;
    @Resource
    private OrderBizService orderBizService;
    @Resource
    private UserService userService;
    @Resource
    private ContractLogService contractLogService;
    @Resource
    private EsignBizService esignBizService;
    @Resource
    private EsignCompanyService esignCompanyService;
    @Resource
    private SubcompanyService subcompanyService;

    @Resource
    private ContractEnterpriseService contractEnterpriseService;


    /**
     * 合同列表
     *
     * @param map
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Override
    public Paged<ContractVo> getContractPage(Map<String, Object> map, Integer pageNum, Integer pageSize) throws Exception {
        Object realNameObj = map.get("realName");
        if (realNameObj != null) {
            String realName = ObjectCastUtil.castString(realNameObj);
            Integer userId = getUserIdByRealName(realName);
            if (null == userId) {
                Paged<ContractVo> paged = new Paged<ContractVo>();
                return getPageTab(paged);
            }
            List<Long> orderCodeList = orderBizService.getOrderCodeByUser(userId);
            if (null == orderCodeList || orderCodeList.size() < 1) {
                Paged<ContractVo> paged = new Paged<ContractVo>();
                return getPageTab(paged);
            }
            map.put("orderCodeList", orderCodeList);
        }

        Paged<ContractDto> contractPage = contractService.getContractPage(map, pageNum, pageSize);

        if (null == contractPage) {
            Paged<ContractVo> paged = new Paged<ContractVo>();
            return getPageTab(paged);
        }

        List<ContractDto> contractDtoList = contractPage.getList();
        if (null == contractDtoList) {
            Paged<ContractVo> paged = new Paged<ContractVo>();
            return getPageTab(paged);
        }


        Map<Long, OrderBizDto> contractOrderInfoMap = getContractOrderInfo(contractDtoList);
        Map<Integer, UserDto> userMap = getUserMap(contractOrderInfoMap);
        List<ContractVo> contractVoList = Convert.toContractVoList(contractDtoList, contractOrderInfoMap, userMap);
        Paged<ContractVo> paged = new Paged<ContractVo>(contractVoList, contractPage.getTotal(), pageSize);
        return getPageTab(paged);
    }

    /**
     * 获取合同订单信息
     *
     * @param contractDtoList
     * @return
     */
    private Map<Long, OrderBizDto> getContractOrderInfo(List<ContractDto> contractDtoList) {
        List<Long> orderCodeList = new ArrayList<>();
        for (ContractDto contractDto : contractDtoList) {
            Long orderCode = contractDto.getOrderCode();
            orderCodeList.add(orderCode);
        }
        return orderBizService.getOrder(orderCodeList);
    }

    /**
     * 获取用户map
     *
     * @param contractOrderInfoMap
     * @return
     */
    private Map<Integer, UserDto> getUserMap(Map<Long, OrderBizDto> contractOrderInfoMap) {
        if (null == contractOrderInfoMap || contractOrderInfoMap.size() < 1) {
            return null;
        }

        List<Integer> userIdList = new ArrayList<>();
        for (Map.Entry<Long, OrderBizDto> entry : contractOrderInfoMap.entrySet()) {
            OrderBizDto orderBizDto = entry.getValue();
            if (null == orderBizDto) {
                continue;
            }
            Integer userId = orderBizDto.getUserId();
            if (null == userId) {
                continue;
            }
            userIdList.add(userId);
        }

        return userService.getUsers(userIdList);
    }

    /**
     * 获取用户id
     *
     * @param realName
     * @return
     */
    private Integer getUserIdByRealName(String realName) {
        Integer userId = null;
        if (StringUtils.isNoneBlank(realName)) {
            UserDto userDto = userService.getUserByRealName(realName);
            if (userDto != null) {
                userId = userDto.getId();
            }
        }
        return userId;
    }


    /**
     * 获取分页tab值
     *
     * @return
     * @throws Exception
     */
    private Paged<ContractVo> getPageTab(Paged<ContractVo> paged) throws Exception {
        Map<Integer, Integer> statusCountMap = contractService.getContractCountByStatus();
        List<TabDto> tabList = new ArrayList<>();
        for (ContractStatusEnum contractStatusEnum : ContractStatusEnum.values()) {
            int value = contractStatusEnum.getValue();
            String name = contractStatusEnum.getName();
            Integer count = 0;
            if (null != statusCountMap && statusCountMap.size() > 0) {
                count = statusCountMap.get(value);
            }

            if (null == count) {
                count = 0;
            }

            TabDto tabDto = new TabDto();
            tabDto.setName(name);
            tabDto.setType(value);
            tabDto.setCount(count);
            tabList.add(tabDto);
        }

        return paged.setTab(tabList);
    }

    /**
     * 子合同列表
     *
     * @param mainOrderCode
     * @return
     * @throws Exception
     */
    @Override
    public List<ContractVo> getSubContractList(Long mainOrderCode) throws Exception {
        List<ContractDto> subContractList = contractService.getSubContractList(mainOrderCode);
        Map<Long, OrderBizDto> contractOrderInfoMap = getContractOrderInfo(subContractList);
        Map<Integer, UserDto> userMap = getUserMap(contractOrderInfoMap);
        return Convert.toContractVoList(subContractList, contractOrderInfoMap, userMap);
    }

    /**
     * 合同日志列表
     *
     * @param map
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Override
    public Paged<ContractLogVo> getInvoiceInfoPage(Map<String, Object> map, Integer pageNum, Integer pageSize) throws Exception {
        Paged<ContractLogVo> contractLogVoPaged = new Paged<>(null, 0, pageSize);
        Paged<ContractLogDto> contractLogDtoPaged = contractLogService.getOrderDealerList(map, pageNum, pageSize);
        if (null == contractLogDtoPaged || null == contractLogDtoPaged.getList() || contractLogDtoPaged.getList().size() <= 0) {
            return contractLogVoPaged;
        }
        BeanUtils.copyProperties(contractLogDtoPaged, contractLogVoPaged);
        List<ContractLogVo> contractLogVoList = new ArrayList<>();
        ContractLogVo contractLogVo = null;
        for (ContractLogDto contractLogDto : contractLogDtoPaged.getList()) {
            contractLogVo = new ContractLogVo();
            BeanUtils.copyProperties(contractLogDto, contractLogVo);
            contractLogVo.setIsCreatedStr(contractLogDto.getIsCreated() == true ? ContractLogCreatedEnum.YES.getName() : ContractLogCreatedEnum.NO.getName());
            contractLogVo.setBusinessTypeStr(ContractLogGoodsTypeEnum.getName(contractLogDto.getBusinessType()));
            contractLogVoList.add(contractLogVo);
        }
        contractLogVoPaged.setList(contractLogVoList);
        return contractLogVoPaged;
    }


    /**
     * 创建公司印章
     *
     * @param list
     * @return
     * @throws Exception
     */
    @Override
    public Boolean createCompanyEsign(List<EsignCompanyCreateVo> list) throws Exception {
        if (list != null && list.size() > 0) {
            List<EsignCompanyBizCreateDto> esignCompanyBizCreateDtos = Convert.toEsignCompanyBizCreateDtoList(list);
            return createEsignCompany(esignCompanyBizCreateDtos);
        } else {
            List<SubcompanyDto> subcompanyDtoList = subcompanyService.getSubcompanyByCityId(null);
            if (null == subcompanyDtoList || subcompanyDtoList.size() < 1) {
                throw new BizException("分子公司不存在");
            }

            Map<Integer, EsignCompanyDto> esignCompanyMap = esignCompanyService.getEsignCompanyMap();
            if (null == esignCompanyMap || esignCompanyMap.size() < 1) {
                List<EsignCompanyBizCreateDto> esignCompanyBizCreateDtos = Convert.toEsignCompanyBizCreateList(subcompanyDtoList);
                return createEsignCompany(esignCompanyBizCreateDtos);
            }

            List<SubcompanyDto> subcompanyList = new ArrayList<>();
            for (SubcompanyDto subcompanyDto : subcompanyDtoList) {
                Integer id = subcompanyDto.getId();
                String horizontalText = subcompanyDto.getHorizontalText();
                String bottomChord = subcompanyDto.getBottomChord();
                String upperChord = subcompanyDto.getUpperChord();
                if (null == id) {
                    continue;
                }
                if (StringUtils.isBlank(horizontalText) && StringUtils.isBlank(upperChord) && StringUtils.isBlank(bottomChord)) {
                    continue;
                }

                EsignCompanyDto esignCompanyDto = esignCompanyMap.get(id);
                if (null == esignCompanyDto) {
                    subcompanyList.add(subcompanyDto);
                    continue;
                }

                String sealData = esignCompanyDto.getSealData();
                if (StringUtils.isBlank(sealData)) {
                    subcompanyList.add(subcompanyDto);
                }
            }

            List<EsignCompanyBizCreateDto> esignCompanyBizCreateDtos = Convert.toEsignCompanyBizCreateList(subcompanyList);
            return createEsignCompany(esignCompanyBizCreateDtos);
        }
    }

    /**
     * 创建用户印章
     *
     * @param list
     * @return
     * @throws Exception
     */
    @Override
    public Boolean createAccountEsign(List<EsignAccountCreateVo> list) throws Exception {
        if (null == list || list.size() < 1) {
            throw new BizException("用户信息为空");
        }

        List<EsignAccountBizCreateDto> esignCompanyBizCreateDtos = Convert.toEsignAccountBizCreateDtoList(list);
        return createEsignAccount(esignCompanyBizCreateDtos);
    }


    /**
     * 创建公司印章
     *
     * @param list
     * @return
     * @throws Exception
     */
    private Boolean createEsignCompany(List<EsignCompanyBizCreateDto> list) throws Exception {
        return esignBizService.createEsignCompany(list);
    }


    /**
     * 创建用户印章
     *
     * @param list
     * @return
     * @throws Exception
     */
    private Boolean createEsignAccount(List<EsignAccountBizCreateDto> list) throws Exception {
        return esignBizService.createEsignAccount(list);
    }

    /**
     * 查询提车单信息
     * @param orderCode
     * @return
     */
    @Override
    public DeliveryVo getDelivery(Long orderCode) {
        List<ContractDto> list = contractService.getContractByOrderCode(orderCode, ContractTypeEnum.EXCLUSIVE_BOOKING_CAR_CONTRACT.getValue());
        if (null == list || list.isEmpty()) {
            return null;
        }
        ContractDto contractDto = list.get(0);
        DeliveryVo vo = new DeliveryVo();
        vo.setContractPath(contractDto.getContractPath());
        vo.setOpName(contractDto.getOpName());
        vo.setOpTime(contractDto.getOpTime());
        return vo;
    }

    /**
     * 企业订单合同编号是否存在
     *
     * @param contractNo 合同编号
     * @return
     */
    @Override
    public boolean getContractEnterpriseIsExist(String contractNo) {
        return contractEnterpriseService.getContractNoExist(contractNo);
    }
}
